package com.game.battle.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.game.battle.common.BattleEnum.EnumSceneUnitType;
import com.game.battle.common.Attr.AttrEffectType;
import com.game.battle.common.buff.Buff;
import com.game.battle.common.map.BattleMap.Rotation;
import com.game.battle.common.math.Vector2;
import com.game.battle.config.BuffConfig;
import com.game.battle.config.XMLTemplateService;
import com.game.message.proto.battle.BattleProtoBuf.MFightUnit;

public abstract class FightSceneUnit implements Cloneable
{
    protected int id = 0;
	public int unitType = EnumSceneUnitType.None.ordinal();
    public GridPosition gridPos;
    protected Shield shield;
    private boolean justDead = false;
	protected Shield tempShield;
	private Map<Integer, Float> buffAttrMap = new HashMap<Integer, Float>();
	private Rotation rotation;

	protected int armorType;

	protected int totalHp;
    protected int currentHp;
    //行动力上限
    protected int totalActionPower;
    protected int currentActionPower;
    //单位距离消耗行动力
    protected int moveCap;
    protected int tempCurrentHp;
    public float deploySkillDamage = 0;
    protected int level;
	protected float radius = 0.6f;
	//攻击力
    protected int attack;
	//防御
    protected int defence;
    //暴击值
    protected int crit;
    //韧性
    protected int tenacity;
    //暴击伤害值
    protected int critDamage;
    //单位距离行动力
    protected int unitCostAction;
    //先手值
    protected int priority;
    //抗性 -有机
    protected int resistance_organic;
    //抗性 -机械
    protected int resistance_machinery;
    //抗性 -合金
    protected int resistance_alloy;
    //抗性 -纤维
    protected int resistance_fibre;
    
    //伤害-穿刺
    protected int damage_puncture;
    //伤害-粉碎
    protected int damage_smash;
    //伤害-冲击
    protected int damage_pound;
    //伤害-切割
    protected int damage_cut;
    
	//用来计算距离用
	public FightSceneUnit targetFightUnit;
	
	//此key为互斥组id
	public ConcurrentHashMap<Integer, Buff> mutexBuffMap = new ConcurrentHashMap<>();
	//此key为buffid
	public ConcurrentHashMap<Integer, List<Buff>> noneMutexBuffMap = new ConcurrentHashMap<>();

    @Override  
    public FightSceneUnit clone() {  
    	FightSceneUnit fightSceneUnit = null;  
        try{  
        	fightSceneUnit = (FightSceneUnit)super.clone();  
        	fightSceneUnit.gridPos = (GridPosition)gridPos.clone();
        	if(shield != null){
        		fightSceneUnit.shield = shield.clone();
        	}
        	if(tempShield != null){
        		fightSceneUnit.tempShield = tempShield.clone();
        	}
        	ConcurrentHashMap<Integer, Buff> cloneMutexBuffMap = new ConcurrentHashMap<>();
        	for(java.util.Map.Entry<Integer, Buff> entry : mutexBuffMap.entrySet()){
        		cloneMutexBuffMap.put(entry.getKey(), entry.getValue().clone());
        	}
        	fightSceneUnit.mutexBuffMap = cloneMutexBuffMap;
        	ConcurrentHashMap<Integer, List<Buff>> cloneNoneMutexBuffMap = new ConcurrentHashMap<>();
        	for(java.util.Map.Entry<Integer, List<Buff>> entry : noneMutexBuffMap.entrySet()){
        		List<Buff> buffList = new ArrayList<>();
        		for(Buff buff : entry.getValue()){
        			buffList.add(buff.clone());
        		}
        		cloneNoneMutexBuffMap.put(entry.getKey(), buffList);
        	}
        	fightSceneUnit.noneMutexBuffMap = cloneNoneMutexBuffMap;
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
        return fightSceneUnit;  
    }  
    
    /**
     * 根据buffid取得
     * @param buffId
     * @return
     */
    public int getBuffCountById(int buffId){
    	int count = 0;
    	BuffConfig buffConfig = XMLTemplateService.buffConfigMap.get(buffId);
    	int group = buffConfig.getGroup();
    	if(group == 0){
    		List<Buff> buffList = noneMutexBuffMap.get(buffId);
    		if(buffList != null){
    			count += buffList.size();
    		}
    	}else{
    		Buff buff = mutexBuffMap.get(group);
    		if(buff != null){
    			count += 1;
    		}
    	}
    	
    	return count;
    }
    
    @Override
    public boolean equals(Object other){
    	 if (this == other)
             return true;
         if (other == null)
             return false;
         if (getClass() != other.getClass())
             return false;
         final FightSceneUnit otherUnit = (FightSceneUnit) other;
          if(this.getId() !=otherUnit.getId())
             return false;
         return true;
    }
    

	public boolean isPlayer()
    {
        return this.unitType == EnumSceneUnitType.Player.ordinal();
    }

    public boolean isEnemy()
    {
        return this.unitType == EnumSceneUnitType.Monster.ordinal();
    }

    public boolean isObstacle()
    {
        return this.unitType == EnumSceneUnitType.Obstacle.ordinal();
    }
    
  	public int getId() {
 		return id;
 	}

 	public void setId(int id) {
 		this.id = id;
 	}
 	
 	 public int getLevel() {
 		return level;
 	}


 	public void setLevel(int level) {
 		this.level = level;
 	}
 	
 	 public int getTotalHp() {
 		return totalHp;
 	}

 	public void setTotalHp(int totalHp) {
 		this.totalHp = totalHp;
 	}
 	
 	 public int getTotalActionPower() {
 		float totalActionPowerAddValue = buffAttrMap.get(AttrEffectType.cap) == null ? 0 : buffAttrMap.get(AttrEffectType.cap);
 		float totalActionPowerAddPer = buffAttrMap.get(AttrEffectType.cap_per) == null ? 0 : buffAttrMap.get(AttrEffectType.cap_per);
 		int power = (int)((totalActionPower + totalActionPowerAddValue) * (100+totalActionPowerAddPer)*0.01f);
 		return power;
 	}


 	public void setTotalActionPower(int totalActionPower) {
 		this.totalActionPower = totalActionPower;
 	}


 	public int getCurrentActionPower() {
 		return currentActionPower;
 	}


 	public void setCurrentActionPower(int currentActionPower) {
 		this.currentActionPower = currentActionPower;
 	}


 	public float getDeploySkillDamage() {
 		return deploySkillDamage;
 	}


 	public void setDeploySkillDamage(float deploySkillDamage) {
 		this.deploySkillDamage = deploySkillDamage;
 	}


 	public int getDefence() {
 		float defenceAddValue = buffAttrMap.get(AttrEffectType.def) == null ? 0 : buffAttrMap.get(AttrEffectType.def);
 		float defenceAddPer = buffAttrMap.get(AttrEffectType.def_per) == null ? 0 : buffAttrMap.get(AttrEffectType.def_per);
 		int defenceValue = (int)((defence + defenceAddValue) * (100+defenceAddPer)*0.01f);
 		return defenceValue;
 	}


 	public void setDefence(int defence) {
 		this.defence = defence;
 	}


 	public int getCrit() {
 		float critAddValue = buffAttrMap.get(AttrEffectType.crit) == null ? 0 : buffAttrMap.get(AttrEffectType.crit);
 		float critAddPer = buffAttrMap.get(AttrEffectType.crit_per) == null ? 0 : buffAttrMap.get(AttrEffectType.crit_per);
 		int critValue = (int)((crit + critAddValue) * (100+critAddPer)*0.01f);
 		return critValue;
 	}


 	public void setCrit(int crit) {
 		this.crit = crit;
 	}


 	public int getTenacity() {
 		float tenacityAddValue = buffAttrMap.get(AttrEffectType.ten) == null ? 0 : buffAttrMap.get(AttrEffectType.ten);
 		float tenacityAddPer = buffAttrMap.get(AttrEffectType.ten_per) == null ? 0 : buffAttrMap.get(AttrEffectType.ten_per);
 		int tenacityValue = (int)((tenacity + tenacityAddValue) * (100+tenacityAddPer)*0.01f);
 		return tenacityValue;
 	}


 	public void setTenacity(int tenacity) {
 		this.tenacity = tenacity;
 	}


 	public int getCritDamage() {
 		float critDamAddValue = buffAttrMap.get(AttrEffectType.critDam) == null ? 0 : buffAttrMap.get(AttrEffectType.critDam);
 		float critDamAddPer = buffAttrMap.get(AttrEffectType.critDam_per) == null ? 0 : buffAttrMap.get(AttrEffectType.critDam_per);
 		int critDamageValue = (int)((critDamage + critDamAddValue) * (100+critDamAddPer)*0.01f);
 		return critDamageValue;
 	}


 	public void setCritDamage(int critDamage) {
 		this.critDamage = critDamage;
 	}


 	public int getUnitCostAction() {
 		float unitCostActionAddValue = buffAttrMap.get(AttrEffectType.moveCap) == null ? 0 : buffAttrMap.get(AttrEffectType.moveCap);
 		float unitCostActionAddPer = buffAttrMap.get(AttrEffectType.moveCap_per) == null ? 0 : buffAttrMap.get(AttrEffectType.moveCap_per);
 		int unitCostActionValue = (int)((unitCostAction + unitCostActionAddValue) * (100+unitCostActionAddPer)*0.01f);
 		return unitCostActionValue;
 	}


 	public void setUnitCostAction(int unitCostAction) {
 		this.unitCostAction = unitCostAction;
 	}


 	public int getPriority() {
 		float priorityAddValue = buffAttrMap.get(AttrEffectType.speed) == null ? 0 : buffAttrMap.get(AttrEffectType.speed);
 		float priorityAddPer = buffAttrMap.get(AttrEffectType.speed_per) == null ? 0 : buffAttrMap.get(AttrEffectType.speed_per);
 		int priorityValue = (int)((priority + priorityAddValue) * (100+priorityAddPer)*0.01f);
 		return priorityValue;
 	}


 	public void setPriority(int priority) {
 		this.priority = priority;
 	}


 	public int getResistance_organic() {
 		float orgAddValue = buffAttrMap.get(AttrEffectType.org) == null ? 0 : buffAttrMap.get(AttrEffectType.org);
 		float orgAddPer = buffAttrMap.get(AttrEffectType.org_per) == null ? 0 : buffAttrMap.get(AttrEffectType.org_per);
 		int orgValue = (int)((resistance_organic + orgAddValue) * (100+orgAddPer)*0.01f);
 		return orgValue;
 	}


 	public void setResistance_organic(int resistance_organic) {
 		this.resistance_organic = resistance_organic;
 	}


 	public int getResistance_machinery() {
 		float macAddValue = buffAttrMap.get(AttrEffectType.mac) == null ? 0 : buffAttrMap.get(AttrEffectType.mac);
 		float macAddPer = buffAttrMap.get(AttrEffectType.mac_per) == null ? 0 : buffAttrMap.get(AttrEffectType.mac_per);
 		int macValue = (int)((resistance_machinery + macAddValue) * (100+macAddPer)*0.01f);
 		return macValue;
 	}


 	public void setResistance_machinery(int resistance_machinery) {
 		this.resistance_machinery = resistance_machinery;
 	}


 	public int getResistance_alloy() {
 		float allAddValue = buffAttrMap.get(AttrEffectType.all) == null ? 0 : buffAttrMap.get(AttrEffectType.all);
 		float allAddPer = buffAttrMap.get(AttrEffectType.all_per) == null ? 0 : buffAttrMap.get(AttrEffectType.all_per);
 		int allValue = (int)((resistance_alloy + allAddValue) * (100+allAddPer)*0.01f);
 		return allValue;
 	}


 	public void setResistance_alloy(int resistance_alloy) {
 		this.resistance_alloy = resistance_alloy;
 	}


 	public int getResistance_fibre() {
 		float fibAddValue = buffAttrMap.get(AttrEffectType.fib) == null ? 0 : buffAttrMap.get(AttrEffectType.fib);
 		float fibAddPer = buffAttrMap.get(AttrEffectType.fib_per) == null ? 0 : buffAttrMap.get(AttrEffectType.fib_per);
 		int fibValue = (int)((resistance_fibre + fibAddValue) * (100+fibAddPer)*0.01f);
 		return fibValue;
 	}


 	public void setResistance_fibre(int resistance_fibre) {
 		this.resistance_fibre = resistance_fibre;
 	}


 	public int getDamage_puncture() {
 		float punAddValue = buffAttrMap.get(AttrEffectType.pun) == null ? 0 : buffAttrMap.get(AttrEffectType.pun);
 		float punAddPer = buffAttrMap.get(AttrEffectType.pun_per) == null ? 0 : buffAttrMap.get(AttrEffectType.pun_per);
 		int punValue = (int)((damage_puncture + punAddValue) * (100+punAddPer)*0.01f);
 		return punValue;
 	}


 	public void setDamage_puncture(int damage_puncture) {
 		this.damage_puncture = damage_puncture;
 	}


 	public int getDamage_smash() {
 		float smaAddValue = buffAttrMap.get(AttrEffectType.sma) == null ? 0 : buffAttrMap.get(AttrEffectType.sma);
 		float smaAddPer = buffAttrMap.get(AttrEffectType.sma_per) == null ? 0 : buffAttrMap.get(AttrEffectType.sma_per);
 		int smaValue = (int)((damage_smash + smaAddValue) * (100+smaAddPer)*0.01f);
 		return smaValue;
 	}


 	public void setDamage_smash(int damage_smash) {
 		this.damage_smash = damage_smash;
 	}


 	public int getDamage_pound() {
 		float impAddValue = buffAttrMap.get(AttrEffectType.imp) == null ? 0 : buffAttrMap.get(AttrEffectType.imp);
 		float impAddPer = buffAttrMap.get(AttrEffectType.imp_per) == null ? 0 : buffAttrMap.get(AttrEffectType.imp_per);
 		int impValue = (int)((damage_pound + impAddValue) * (100+impAddPer)*0.01f);
 		return impValue;
 	}


 	public void setDamage_pound(int damage_pound) {
 		this.damage_pound = damage_pound;
 	}


 	public int getDamage_cut() {
 		float incAddValue = buffAttrMap.get(AttrEffectType.inc) == null ? 0 : buffAttrMap.get(AttrEffectType.inc);
 		float incAddPer = buffAttrMap.get(AttrEffectType.inc_per) == null ? 0 : buffAttrMap.get(AttrEffectType.inc_per);
 		int incValue = (int)((damage_cut + incAddValue) * (100+incAddPer)*0.01f);
 		return incValue;
 	}


 	public void setDamage_cut(int damage_cut) {
 		this.damage_cut = damage_cut;
 	}

 	public int getCurrentHp() {
 		float hpAddValue = buffAttrMap.get(AttrEffectType.hp) == null ? 0 : buffAttrMap.get(AttrEffectType.hp);
 		float hpAddPer = buffAttrMap.get(AttrEffectType.hp_per) == null ? 0 : buffAttrMap.get(AttrEffectType.hp_per);
 		int hp = (int)((currentHp + hpAddValue) * (100+hpAddPer)*0.01f);
 		return hp;
 	}

 	public void setCurrentHp(int currentHp) {
 		this.currentHp = currentHp;
 	}
 	
	public int getTempCurrentHp() {
		return tempCurrentHp;
	}

	public void setTempCurrentHp(int tempCurrentHp) {
		this.tempCurrentHp = tempCurrentHp;
	}
	
	public float getRadius() {
		return radius;
	}


	public void setRadius(float radius) {
		this.radius = radius;
	}
	
	public int getAttack() {
		float attackAddValue = buffAttrMap.get(AttrEffectType.att) == null ? 0 : buffAttrMap.get(AttrEffectType.att);
 		float attackAddPer = buffAttrMap.get(AttrEffectType.att_per) == null ? 0 : buffAttrMap.get(AttrEffectType.att_per);
 		int attackValue = (int)((attack + attackAddValue) * (100+attackAddPer)*0.01f);
		return attackValue;
	}

	public void setAttack(int attack) {
		this.attack = attack;
	}
	
	public int getUnitType() {
		return unitType;
	}

	public void setUnitType(int unitType) {
		this.unitType = unitType;
	}

	public GridPosition getGridPos() {
		return gridPos;
	}

	public void setGridPos(GridPosition gridPos) {
		this.gridPos = gridPos;
	}

	public int getMoveCap() {
		float moveCapAddValue = buffAttrMap.get(AttrEffectType.moveCap) == null ? 0 : buffAttrMap.get(AttrEffectType.moveCap);
 		float moveCapAddPer = buffAttrMap.get(AttrEffectType.moveCap_per) == null ? 0 : buffAttrMap.get(AttrEffectType.moveCap_per);
 		int moveCapValue = (int)((moveCap + moveCapAddValue) * (100+moveCapAddPer)*0.01f);
 		return moveCapValue;
	}

	public void setMoveCap(int moveCap) {
		this.moveCap = moveCap;
	}

	public FightSceneUnit getTargetFightUnit() {
		return targetFightUnit;
	}

	public void setTargetFightUnit(FightSceneUnit targetFightUnit) {
		this.targetFightUnit = targetFightUnit;
	}

	public boolean isDead() {
		return isDead;
	}

	public void setDead(boolean isDead) {
		this.isDead = isDead;
	}

	public void setBoss(boolean isBoss) {
		this.isBoss = isBoss;
	}
	
	public Shield getShield() {
		return shield;
	}

	public void setShield(Shield shield) {
		this.shield = shield;
	}
	
	public Shield getTempShield() {
		return tempShield;
	}

	public void setTempShield(Shield tempShield) {
		this.tempShield = tempShield;
	}
	
	public boolean isJustDead() {
		return justDead;
	}

	public void setJustDead(boolean justDead) {
		this.justDead = justDead;
	}
	
	public Map<Integer, Float> getBuffAttrMap() {
		return buffAttrMap;
	}
	
	public int getArmorType() {
		return armorType;
	}

	public void setArmorType(int armorType) {
		this.armorType = armorType;
	}
	
	public Rotation getRotation() {
		return rotation;
	}

	public void setRotation(Rotation rotation) {
		this.rotation = rotation;
	}


 	
    protected boolean isDead = false;


    protected boolean isBoss = false;

    public boolean isBoss()
    {
        return this.unitType == EnumSceneUnitType.Monster.ordinal() && isBoss;
    }

	/**
	 * 扣血
	 */
	public void subHp() {
		this.currentHp = 0;
	}

	public abstract MFightUnit.Builder toProto();

	public void takeEffect() {
		if(shield != null){
			tempShield = shield.clone();
		}
		this.tempCurrentHp = getCurrentHp();
		
		int shieldPower = shield == null ? 0 : shield.getCurrentPower();
		if(deploySkillDamage < shieldPower && shield != null ){
			shield.setCurrentPower(shieldPower - Math.abs((int)deploySkillDamage));
		}else {
			shield = null;
			int leftDamage = (int)deploySkillDamage - shieldPower;
			setCurrentHp(this.getCurrentHp() - leftDamage);
		}
		deploySkillDamage = 0;
	}

	public void resetByClone(Map<Integer, FightSceneUnit> effectOrigiFightSceneUnits, FightSceneUnit unit) {
//		if(unit.tempShield != null){
//			this.shield = unit.tempShield.clone();
//		}
//		this.currentHp = unit.currentHp;
		
		//前面是之前的方式 现在把所有的以前的状态都记录了一下 直接恢复就行了（暂时只处理buff）
		FightSceneUnit originUnit = effectOrigiFightSceneUnits.get(unit.getId());
		if(originUnit != null){
			//根据之前的buff状态克隆回来
			this.currentHp = originUnit.currentHp;
			if(originUnit.shield != null){
				this.shield = originUnit.shield.clone();
			}
			
			ConcurrentHashMap<Integer, Buff> cloneMutexBuffMap = new ConcurrentHashMap<>();
	    	for(java.util.Map.Entry<Integer, Buff> entry : originUnit.mutexBuffMap.entrySet()){
	    		cloneMutexBuffMap.put(entry.getKey(), entry.getValue().clone());
	    	}
	    	this.mutexBuffMap = cloneMutexBuffMap;
	    	ConcurrentHashMap<Integer, List<Buff>> cloneNoneMutexBuffMap = new ConcurrentHashMap<>();
	    	for(java.util.Map.Entry<Integer, List<Buff>> entry : originUnit.noneMutexBuffMap.entrySet()){
	    		List<Buff> buffList = new ArrayList<>();
	    		for(Buff buff : entry.getValue()){
	    			buffList.add(buff.clone());
	    		}
	    		cloneNoneMutexBuffMap.put(entry.getKey(), buffList);
	    	}
	    	this.noneMutexBuffMap = cloneNoneMutexBuffMap;
		}
		refreshBuffAttr();
		
		//因为每次都会更新这个值 所以先不恢复为0 （为解决恢复物体的问题）
//		deploySkillDamage = 0;
	}
	
//	public Shield getCurrentShield(){
//		if(shieldStack.size() == 0){
//			return null;
//		}
//	}

	public int getTargetDistance() {
		if(targetFightUnit == null){
			return 0;
		}
		Vector2 posVector2 = new Vector2(this.gridPos.getX(),this.gridPos.getY());
		Vector2 targetVector2 = new Vector2(targetFightUnit.gridPos.getX(),targetFightUnit.gridPos.getY());
		Vector2 forwardVector2 = Vector2.sub(targetVector2, posVector2);
		float length = forwardVector2.sqrMagnitude();
		return (int)Math.abs((length - targetFightUnit.radius) * 10);
	}
	
	/**
	 * 真正执行阶段的伤害
	 * @param damage
	 */
	public void takeRealEffect_damage(int damage) {
		this.tempCurrentHp = getCurrentHp();
		int shieldPower = shield == null ? 0 : shield.getCurrentPower();
		if(damage < shieldPower){
			shield.setCurrentPower(shieldPower - damage);
		}else {
			shield = null;
			int leftDamage = damage - shieldPower;
			this.setCurrentHp(this.getCurrentHp() - leftDamage);
		}
		if(this.getCurrentHp() <= 0){
			this.setJustDead(true);
		}
		
	}
	
	/**
	 * 真正执行阶段的治疗
	 * @param damage
	 */
	public void takeRealEffect_heal(int heal) {
		this.tempCurrentHp = getCurrentHp();
		this.currentHp = Math.min(this.getTotalHp(),this.getCurrentHp()+heal);
	}
	
	/**
	 * 消耗行动力
	 * @param actionCost
	 */
	public void costActionPower(int actionCost) {
		this.currentActionPower -= actionCost;
	}
	
	/**
	 * 增加行动力
	 * @param actionCost
	 */
	public void addActionPower(int actionPower) {
		this.currentActionPower += actionPower;
	}
	/**
	 * 刷新buff属性
	 */
	public void refreshBuffAttr(){
		buffAttrMap.clear();
		for(java.util.Map.Entry<Integer, Buff> entry : mutexBuffMap.entrySet()){
			Buff buff = entry.getValue();
			if(buff.isActive()){
				List<String> effectList = buff.getEffectList();
				if(effectList == null || effectList.size() == 0){
					continue;
				}
				for(String eff : effectList){
					if(eff == null || "".equals(eff)){
						continue;
					}
					String[] params = eff.split(",");
					int effect = Integer.valueOf(params[0]);
					if(effect > 1000){//只算加属性的
						continue;
					}
					float effectNum = Float.valueOf(params[1]);
					effectNum += buffAttrMap.get(effect) == null ? 0 : buffAttrMap.get(effect);
					buffAttrMap.put(effect, effectNum);
				}
				
			}
    	}
    	for(java.util.Map.Entry<Integer, List<Buff>> entry : noneMutexBuffMap.entrySet()){
    		List<Buff> buffList = entry.getValue();
    		for(Buff buff : buffList){
    			if(buff.isActive()){
    				List<String> effectList = buff.getEffectList();
    				if(effectList == null || effectList.size() == 0){
    					continue;
    				}
					for(String eff : effectList){
						if(eff != null && !"".equals(eff)){
							String[] params = eff.split(",");
	    					int effect = Integer.valueOf(params[0]);
	    					if(effect > 1000){//只算加属性的
	    						continue;
	    					}
	    					float effectNum = Integer.valueOf(params[1]);
	    					effectNum += buffAttrMap.get(effect) == null ? 0 : buffAttrMap.get(effect);
	    					buffAttrMap.put(effect, effectNum);
						}
    				}
    			}
    		}
    	}
	}
	
	/**
	 * 上buff
	 * @param attacker
	 * @param buffId
	 */
	public void addBuff(FightSceneUnit attacker, int buffId) {
		BuffConfig buffConfig = XMLTemplateService.buffConfigMap.get(buffId);
		if(buffConfig == null){
			return;
		}
		Buff addBuff = new Buff(attacker.getId(),buffConfig);
		//互斥组
		int group = buffConfig.getGroup();
		//根据有无互斥组分别处理 0为无互斥组
		if(group > 0){
			mutexBuffMap.put(group, addBuff);
		}else{//buff无互斥组的情况
			if(!noneMutexBuffMap.contains(buffId)){
				List<Buff> buffs = new ArrayList<>();
				buffs.add(addBuff);
				noneMutexBuffMap.put(buffId, buffs);
			}else {//已经存在此id的buff的情况
				//遍历所有此id的判断来源
				List<Buff> buffList = noneMutexBuffMap.get(buffId);
				//不同来源互斥的话 那肯定是替换了
				if(buffConfig.getMutex() == 1){
					buffList.clear();
				}else {
					for(int i=0; i<buffList.size(); i++){
						Buff buff = buffList.get(i);
						if(attacker.getId() == buff.getSourceUnitId()){
							buffList.remove(i);
						}
					}
				}
				buffList.add(addBuff);
			}
		}
		refreshBuffAttr();
	}

	/**
	 * 回合刷新buff
	 */
	public void roundRefreshBuff() {
		for(java.util.Map.Entry<Integer, Buff> entry : mutexBuffMap.entrySet()){
			Buff buff = entry.getValue();
			if(!buff.isActive()){
				buff.setActive(true);
			}else{
				int leftRound = buff.getLeftRound()-1;
				if(leftRound <= 0){
					mutexBuffMap.remove(buff.getGroup());
				}else{
					buff.setLeftRound(leftRound);
				}
			}
    	}
    	for(java.util.Map.Entry<Integer, List<Buff>> entry : noneMutexBuffMap.entrySet()){
    		List<Buff> buffList = entry.getValue();
    		for(int i = 0; i<buffList.size(); i++){
    			Buff buff = buffList.get(i);
    			if(!buff.isActive()){
    				buff.setActive(true);
    			}else{
    				int leftRound = buff.getLeftRound()-1;
    				if(leftRound <= 0){
    					buffList.remove(i);
    				}else{
    					buff.setLeftRound(leftRound);
    				}
    			}
    		}
    	}
    	
    	refreshBuffAttr();
	}
	
	/**
	 * 移除buff
	 * @param buffId
	 */
	public void removeBuff(int buffId) {
		BuffConfig buffConfig = XMLTemplateService.buffConfigMap.get(buffId);
		if(buffConfig.getGroup() == 0){
			noneMutexBuffMap.remove(buffId);
		}else{
			mutexBuffMap.remove(buffConfig.getGroup());
		}
	}
	
	/**
	 * 移除所有buff
	 */
	public void clearAllBuffs() {
		noneMutexBuffMap.clear();
		mutexBuffMap.clear();
		refreshBuffAttr();
	}
	
	/**
	 * 根据属性类型取得属性（）
	 * @param damageAttType
	 * @return
	 */
	public int getDamageAttrByType(int damageAttType) {
		if(damageAttType == 1){
			return getDamage_puncture();
		}else if(damageAttType == 2){
			return getDamage_smash();
		}else if(damageAttType == 3){
			return getDamage_pound();
		}else if(damageAttType == 4){
			return getDamage_cut();
		}
		return 0;
	}
	
	/**
	 * 根据属性类型取得属性（）
	 * @param damageAttType
	 * @return
	 */
	public int getDefenceAttrByType(int defenceAttType) {
		if(defenceAttType == 1){
			return getResistance_organic();
		}else if(defenceAttType == 2){
			return getResistance_machinery();
		}else if(defenceAttType == 3){
			return getResistance_alloy();
		}else if(defenceAttType == 4){
			return getResistance_fibre();
		}
		
		return 0;
	}
	
	/**
	 * 根据类型取得buff效果（对应buff效果表 此方法取得的是天赋和buff都有的 1000到3000之间的效果）
	 * @param number
	 * @return
	 */
	public List<HashMap<Integer, Integer>> getBuffEffectListByType(int effectType) {
		List<HashMap<Integer, Integer>> buffEffectList = new ArrayList<>();
		for(java.util.Map.Entry<Integer, Buff> entry : mutexBuffMap.entrySet()){
			Buff buff = entry.getValue();
			if(buff.isActive()){
				List<String> effectList = buff.getEffectList();
				if(effectList == null || effectList.size() == 0){
					continue;
				}
				for(String eff : effectList){
					if(eff == null || "".equals(eff)){
						continue;
					}
					String[] params = eff.split(",");
					int effect = Integer.valueOf(params[0]);
					float effectNum = Float.valueOf(params[1]);
					if(effect % 1000 == effectType){
						HashMap<Integer, Integer> map = new HashMap<>();
						map.put(effect, (int)effectNum);
						buffEffectList.add(map);
					}
				}
				
			}
    	}
    	for(java.util.Map.Entry<Integer, List<Buff>> entry : noneMutexBuffMap.entrySet()){
    		List<Buff> buffList = entry.getValue();
    		for(Buff buff : buffList){
    			if(buff.isActive()){
    				List<String> effectList = buff.getEffectList();
    				if(effectList == null || effectList.size() == 0){
    					continue;
    				}
					for(String eff : effectList){
						if(eff != null && !"".equals(eff)){
							String[] params = eff.split(",");
	    					int effect = Integer.valueOf(params[0]);
	    					float effectNum = Integer.valueOf(params[1]);
	    					if(effect % 1000 == effectType){
	    						HashMap<Integer, Integer> map = new HashMap<>();
	    						map.put(effect, (int)effectNum);
	    						buffEffectList.add(map);
	    					}
						}
    				}
    			}
    		}
    	}
		return buffEffectList;
	}
}